/*	Program For Testing                */
#include<math.h>
#include<time.h>
#include<stdio.h>
#include<stdlib.h>

unsigned long iv,hv,ov;

double     *in_vect,
	  *out_vect,
	  *calculated_out_vect,
	  *hidden_vect,
	  *max_val,
	  *min_val,
	  **input_hidden,
	  **hidden_output;


double error=0.0;

int misclassification=0;

char	 *Test_source_path ="data1_mix.txt",/*ENTER TEST   FILE PATH*/
	 *result_path ="out1_res5.txt",/*  ENTER RESULT STORING PATH*/
	 *weight_matrix_path="w.txt";

FILE *fp_source,*fp_result,*fp_master;

double   activation  (double);
void    Test        (void);
void    initNet     (unsigned long,unsigned long, unsigned long);
void    BuildWeight (void);

unsigned long datasets = 0;

void main(void)
{
	unsigned long i,j,l;
	double p1;
	
/******************   INITIALIZE THE NETWORK*****************/
	initNet(2, 3, 2);
/************************************************************/
	fp_result=fopen(result_path,"w");
/******************   INITIALIZE THE WEIGHT MATRIX*************/
	BuildWeight();
	fp_source=fopen(Test_source_path,"r");
	datasets = 0;
	while(!feof(fp_source))if(fgetc(fp_source)=='\n')datasets++;
	rewind(fp_source);
	for(l=0;l<datasets;l++){
	   for(i=0;i<iv;i++){
	      fscanf(fp_source,"%lf",&p1);
	      fprintf(fp_result,"%+09.3lf ",p1);
	      in_vect[i]= p1;
	      }
	      j=i;
	   for(i=0;i<ov;i++){
	      fscanf(fp_source,"%lf",&p1);
	      out_vect[i]= p1;
	      j++;
	      }
	      Test();
	      }
	      fclose(fp_source);
	      fclose(fp_result);
              
/********************FREEING MEMORY******************************/
	free(max_val);
	free(min_val);
	free(in_vect);
	free(hidden_vect);
	free(out_vect);
	free(calculated_out_vect);
	for(i=0;i<hv;i++)free(hidden_output[i]);
	free(hidden_output);
	for(i=0;i<iv;i++)free(input_hidden[i]);
	free(input_hidden);
/*****************************************************************/

}

double activation(double x)
{
	return (1.0/(1.0+(double)exp((double)(-x))));
}

void Test(void)
{
	unsigned long r,k=0;
	double x=0,difference=0;

	for(k=0;k<hv;k++){		/* CALCULATION OF HIDDEN VECTOR*/
		x=0;
		for(r=0;r<iv;r++)x+=(input_hidden[r][k]*in_vect[r]);
		hidden_vect[k]=activation(x);
	}

	for(k=0;k<ov;k++){		/* CALCULATION OF OUTPUT VECTOR */
		x=0;
		for(r=0;r<hv;r++)x+=(hidden_output[r][k]*hidden_vect[r]);
		calculated_out_vect[k]=activation(x);
		calculated_out_vect[k]=calculated_out_vect[k]*;
		out_vect[k]=out_vect[k];
		difference = (calculated_out_vect[k] - out_vect[k]);
				
		
		if(k<(ov-1))
			fprintf(fp_result,"%+09.3lf %+09.3lf %+09.3lf ",out_vect[k],calculated_out_vect[k],difference);
		else
			fprintf(fp_result,"%+09.3lf %+09.3lf %+09.3lf",out_vect[k],calculated_out_vect[k],difference);

			}
	
                fprintf(fp_result,"\n");
                        
	
	return;
}

void initNet(unsigned long Input_Vect,unsigned long Hidden_Vect, unsigned long Output_Vect)
{
	unsigned long i,j;
	double val;
	unsigned long dummy;
	iv = Input_Vect;
	ov = Output_Vect;
	hv = Hidden_Vect;
	
	in_vect=(double *)calloc((iv),sizeof(double));

	hidden_vect=(double *)calloc((hv),sizeof(double));

	out_vect=(double *)calloc((ov),sizeof(double));

	calculated_out_vect=(double *)calloc((ov),sizeof(double));

	hidden_output =(double **)calloc((hv),sizeof(double *));

	for(i=0;i<hv;i++)hidden_output[i] =(double *)calloc((ov),sizeof(double));
	input_hidden=(double **)calloc((iv),sizeof(double *));

	for(i=0;i<iv;i++)input_hidden[i] =(double *)calloc((hv),sizeof(double));


	

	return;
}

void BuildWeight(void)
{
	unsigned long i,j;
	double temp;
	FILE *fp_weight=fopen(weight_matrix_path,"r");
	fscanf(fp_weight,"%lu %lf %lf",&hv,&temp,&temp);
	for(i=0;i<hv;i++){			/* INITIALIZING HIDDEN - OUTPUT MATRIX */
		for(j=0;j<ov;j++)fscanf(fp_weight,"%lf",&hidden_output[i][j]);
	}
	for(i=0;i<iv;i++){			/* INITIALIZING INPUT - HIDDEN MATRIX  */
		for(j=0;j<hv;j++)fscanf(fp_weight,"%lf",&input_hidden[i][j]);
	}
	fclose(fp_weight);
	return;

}